﻿#light

open System
open System.Collections.Generic
open System.Runtime.InteropServices
open Dwarf.Managed

[<DllImport(@"CliTools.dll")>]
extern void start()

[<DllImport(@"CliTools.dll")>]
extern double finish()

[<DllImport(@"CliTools.dll")>]
extern void usage()

let solve(dwarfConfigurator : Configurator) : List<int> =
    let mutable positions = new List<int>()     // main list for results

    let mutable statesVal = null : int[,]       // matrix of states

    let mutable patternVal = null  : string     //
    let mutable initialPositionVal = 0          //
    let mutable contentVal = null : string      // values of fsmType members for each string part

    dwarfConfigurator.GetData(&patternVal, 1)
    contentVal <- dwarfConfigurator.GetNextInputPart()
    statesVal <- FiniteStateMachineFSharpMethod.constructStates(patternVal)    

    while not (contentVal = null) do
        let contentLengthVal = contentVal.Length - (int)contentVal.[contentVal.Length - 1] - 1
        let fsm : FiniteStateMachineFSharpMethod.fsmType =
            {
                pattern = patternVal;
                content = contentVal;
                states = statesVal;
                stateDimensionCoincidence = patternVal.Length;
                initialPosition = initialPositionVal;
                positions = new List<int>();
                contentLength = contentLengthVal
            }
        FiniteStateMachineFSharpMethod.solve(fsm)
        initialPositionVal <- initialPositionVal + contentLengthVal
        contentVal <- dwarfConfigurator.GetNextInputPart()
        positions.AddRange(fsm.positions)

    positions    

let main() =
    let args = System.Environment.GetCommandLineArgs()
    let dwarfConfigurator = new Configurator(args)
    dwarfConfigurator.WriteSettings() 
    start()

    let positions = solve(dwarfConfigurator)

    let time = finish()
    Console.WriteLine("Total count of pattern entries: " + (string)positions.Count);
    dwarfConfigurator.Close(time, positions)

main()
